Skip to content

Replace _has<PlotType> variables with '_has()' fullLayout method #491

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
May 11, 2016

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Apr 28, 2016

@mdtusz @alexcjohnson

Rationale

Our set of hidden plot type variables _hasCartesian, _hasGL3D, _hasGeo, _hasGL2D, _hasPie and most recently _hasTernary has grown out-of-control.

We need a better way to keep track of the plot types present on a graph AND loop over the required plot modules. Enter the fullLayout._basePlotModules array and the fullLayout._has method.

In brief

This PR:

  • Makes Plotly.plot is agnostic to base plot modules. Consequently, users can now write their own basePlotModule.
  • Moves the list of trace modules required for a given graph from gd._modules to fullLayout._modules (it is much easier to work with from fullLayout)
  • Keeps track of the plot modules required for a given graph in fullLayout._basePlotModules
  • Make pie traces use their own basePlotModule instead of being a special case in the Cartersian base plot module
  • Attaches a _has method to fullLayout to check the presence of a particular plot type e.g. fullLayout._has('gl3d') return true if the given graph has a gl3d subplot. The _has method deprecates the _hasCartesian, _hasGeo ... fullLayout fields.
  • All _hasCartesian, _hasGeo ... fields have been replaced by their _has('') equivalent
    Important, _hasCartesian, _hasGeo ... are still defined for backward compatibility as some apps (e.g. the old plot.ly workspace) uses them.

Going forward, patterns that require checking for which plot types are present on a given graph should be discouraged. All plot types should have compatible components meaning that a loop over the present basePlotModules should suffice in all cases.

In this regard, the most problematic component at the moment is the modebar. In a future PR, we should try to make the modebar a component of each plot type e.g. Cartesian.modeBar, Geo.modeBar ... etc.

-  as a replacement for _hasCartesian, _hasGeo, _hadGL3D, etc.
- revert after replacing all _has with _has()
- so that fullLayout.has('pie') returns true
- note that fullLayout.has('cartesian') also returns true now
  as pie trace use the cartesian plot module.
- so that 'hovermode' is set and toggled properly.
}

// attach helper method
newFullLayout._has = hasPlotType.bind(newFullLayout);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mdtusz I know this could be more verbose, but I really like the look of e.g. fullLayout._has('geo')

@alexcjohnson
Copy link
Collaborator

💯 for the idea. It's going to be a bit slower than all the individual flags but doesn't look like it's called much in hot paths, so I think we're fine. I wonder if we can even turn this block into a loop over fullLayout._modules - or actually, that needs to be a loop over basePlotModules, which makes me wonder if we shouldn't make a fullLayout._basePlotModules too?

@etpinard
Copy link
Contributor Author

I wonder if we can even turn this block into a loop over fullLayout._modules - or actually, that needs to be a loop over basePlotModules, which makes me wonder if we shouldn't make a fullLayout._basePlotModules too?

That's the goal. But, I wanted to leave that for another PR. Replacing all those _has<PlotType> variable will turn into a lot of changed lines.

I did experiment with a fullLayout._basePlotModules list, it works great except for the orphan axes case, where we would have to make sure that Catersian.plot gets calls even if there's no 'cartesian' trace on the graph.

To note, a loop over fullLayout._basePlotModules list would users to write their own pluggable basePlotModule. For example, our Mapbox integration could be simply plotly.js plugin instead of being part of this repo.

@alexcjohnson
Copy link
Collaborator

To note, a loop over fullLayout._basePlotModules list would users to write their own pluggable basePlotModule.

Sure... Though it's better for the ecosystem if those modules eventually make it into the main repo - so users can still share plots, including via plot.ly.

etpinard added 3 commits May 3, 2016 14:25
- so that _has??? are one-to-one with base plot modules
- handle case where base plot module attrRegex isn't defined
  in plot schema.
etpinard added 9 commits May 6, 2016 14:04
 - useful to fill fullLayout._modules and
   fullLayout._basePlotModules
- and in _basePlotModules in fullLayout._has() instead of
  loop over _modules
- in Plots.cleanPlot (use basePlotModules list in old fullLayout)
- in Plots.supplyLayoutModulesDefaults (making those !_has??? obsolete)
- in main drawData function (instead of _has??? switch block)
- if found, the restyle calls required a full replot
- Plots.redrawText and Snapshot redraw work with
  every plot type except polar
- continue if polar trace is detected in main supply default
  trace loop
- don't assign _hasPolar (it didn't have to correct value anyway)
- no need to loop over all the registered module,
  only the ones that appear in the data suffices.
etpinard added 5 commits May 6, 2016 14:38
- so that it works in cases where _has isn't defined e.g.
  via Plotly.purge().
- to more easily mock _has in test layouts
- so that orphan axes are considered hasCartesian still
- IMPORTANT: we must keep ref to _has??? for backward compatibility
@etpinard
Copy link
Contributor Author

etpinard commented May 6, 2016

@alexcjohnson @mdtusz I decided to through with making Plotly.plot agnostic to basePlotModules in this PR.

I completely re-wrote the PR description. This PR is quite massive, but the commits history starting from May 6 should be easy to read.

// to not go through a full replot
var doPlotWhiteList = ['cartesian', 'pie', 'ternary'];
fullLayout._basePlotModules.forEach(function(_module) {
if(doPlotWhiteList.indexOf(_module.name) === -1) doplot = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In restyle, which is more general than

if(fullLayout._hasGL3D || fullLayout._hasGeo || fullLayout._hasGL2D) doplot = true;

in an effort to support custom basePlotModules

@mdtusz
Copy link
Contributor

mdtusz commented May 9, 2016

Don't see anything wrong here. We'll have to remember to swap that block of fullLayout._has???'s out once the workspace doesn't need them anymore, but looks good to me (once tests pass)!

💃

@@ -95,7 +95,7 @@ module.exports = function supplyLayoutDefaults(layoutIn, layoutOut, fullData) {
// make sure that plots with orphan cartesian axes
// are considered 'cartesian'
if(xaListCartesian.length && yaListCartesian.length) {
layoutOut._hasCartesian = true;
Lib.pushUnique(layoutOut._basePlotModules, Plots.subplotsRegistry.cartesian);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important ⏫

@etpinard etpinard merged commit 1903061 into master May 11, 2016
@etpinard etpinard deleted the has-plot-type branch May 11, 2016 18:16
@etpinard etpinard mentioned this pull request May 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants